Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NEW] Granular permissions for settings #8942

Conversation

mrsimpson
Copy link
Collaborator

@mrsimpson mrsimpson commented Nov 24, 2017

Closes #8771

@RocketChat/core This PR adds the ability to allow a role to change only dedicated settings.
This is necessary in order to e. g. allow a user to change the colors of his Rocket.Chat without compromising critical settings such as LDAP-connectivity.

Though the actual purpose is already fulfilled, this PR has to be considered WIP due to the limitations mentioned below.

@Developers (particularly frontend-developers): I need assistance to fix the "final" (mostly UI) bugs

What works

  • Permissions for each and every setting is created automatically
  • The permissions-UI is extended to visualize and manage all setting-permissions just like normal permissions.
  • The settings-UI in the admin-overview displays the selected settings for the role
  • setting-based permissions are respected/validated when changing a setting
  • permissions are reactive

What could be improved

  • In general, the permissions-UI is not beautiful. This is due to the huge width of the permissions table. Any help on that is appreciated - though @engelgabriel said you'd redesign the look anyway. Currently, there's a CSS-hack which does not work in all browsers to make the header take the full width. There has to be another option, but I'm not a CSS-native.

Impressions

Configuring the permissions

setting-permissions

There is one explicit permission which makes the whole set applicable.
Whether this is a good idea, I am not convinced myself. The permission could be determined.

selected-settings

Effect

effect reduced settings

…ns' to see and change the affected settings.

However, this is not reactive: Once the permissions for a particular setting are changed, the user needs to log  off and on again before it becomes effective in the UI.
This is most probably a consequence of the CachedCollection. This collection needed to be changed on permission-change.
In the backend however, the permissions become effective immediately.
@gdelavald
Copy link
Contributor

This is great, thanks for the PR. We'll check if we have people available to help on the needed changes, else I'm sure the community can help improving it

Copy link
Collaborator Author

@mrsimpson mrsimpson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a couple of fixes - and reverted some development which was done earlier.
Now, it works fine from my side: reactively without any frontend or backend exceptions ;)
Some explanations why I changed what and where I was looking for better solutions I did not find below.

package.json Outdated Show resolved Hide resolved
@@ -1,36 +1,76 @@
<template name="permissionsTable">
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created a template for the table as both permission tables follow the same scheme.

@@ -1,66 +1,121 @@
/* globals ChatPermissions */
import {permissionLevel} from '../../lib/rocketchat';

const whereNotSetting = {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$ne is not supported by Minimongo. Thus, had to fallback to $where. Still, this does not seem to work, see the .filter-comment some lines below

sort: {
_id: 1
permissions() {
return ChatPermissions.find(whereNotSetting, //the $where seems to have no effect - filtered as workaround after fetch()
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any idea why the $where has no effect?

@@ -1 +1,5 @@
RocketChat.authz = {};

export const permissionLevel = {
SETTING: 'setting'
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can imagine that there are other levels as well, such as the permission to change dedicated roles, thus making it a map

@@ -20,4 +27,12 @@ Meteor.methods({

RocketChat.models.Permissions.on('changed', (type, permission) => {
RocketChat.Notifications.notifyLoggedInThisInstance('permissions-changed', type, permission);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this not be notifyLogged() it was like that earlier, so I didn't change it...

});
}

setupListener(eventType, eventName) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The redefinition is necessary as the change of permissions has to trigger the Settings-collection to be refreshed. We'll have to listen to an event "authorization changed".

// private settings also need to listen to a change of authorizationsfor the setting-based authorizations
RocketChat.Notifications[eventType || this.eventType](eventName || this.eventName, (t, record) => {
this.log('record received', t, record);
if (t === 'auth') {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there was an enumeration-constant, I'd be happy to use it ;)

RocketChat.Notifications[eventType || this.eventType](eventName || this.eventName, (t, record) => {
this.log('record received', t, record);
if (t === 'auth') {
if (! (RocketChat.authz.hasAllPermission([`change-setting-${ record._id }`, 'manage-selected-settings'])
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The concatenation change-setting-${ record._id } should be reusable function of the auth-package. However, as rocketchat:lib is lower than rocketchat:auth, this is not possible.
For simplicity (and worse maintainability) I just green-coded that...

@mrsimpson mrsimpson changed the title [NEW] #8771 - fine granular settings permissions (WIP) [NEW] #8771 - fine granular settings permissions Dec 6, 2017
@mrsimpson
Copy link
Collaborator Author

removed WIP as this is actually done, except beautification

@Wirone
Copy link

Wirone commented Jan 26, 2018

Is there possibility to merge this feature in nearest future?

About beautification: maybe it could be transposed from table into tokenized rows? Each row would be a role with autocompleted and tokenized select field. So roles with less privileges would take less space and those with more privileges would take more space. Now every role takes exact space (column) and there are every privileges displayed regardless if they're checked or not. In my concept only chosen privileges would be displayed for each row and each privilege could be removed/added.

@mrsimpson
Copy link
Collaborator Author

mrsimpson commented Jan 28, 2018

@RocketChat/core I merged the current master in order to allow other users who build their own version to merge this branch. If you could let me know what you need to get it merged (and when!), I'll merge develop. For other devs: c7d7145 is compatible with 0.60.4

@@ -41,6 +40,14 @@ Meteor.methods({
}
settings.updateById(_id, value, editor);
});
// Throw messages for settings that are not allowed to save!
if (settingsNotAllowed.length) {
throw new Meteor.Error('error-action-not-allowed', 'Editing settings is not allowed', {
Copy link
Collaborator Author

@mrsimpson mrsimpson Aug 8, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error is not propagated to the user, just like it was not done earlier

if (Meteor.userId() === null) {
throw new Meteor.Error('error-action-not-allowed', 'Editing settings is not allowed', {
method: 'saveSetting',
});
}

if (!hasPermission(Meteor.userId(), 'edit-privileged-setting')) {
throw new Meteor.Error('error-action-not-allowed', 'Editing settings is not allowed', {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This actually failed the saving of multiple settings on the first permission violation. Since now multiple settings can be saved at once and some may fail while others wont, I moved this error handling into a loop down below.

Copy link
Collaborator Author

@mrsimpson mrsimpson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ggazzo I now successfully merged the feature to 1.4-develop.
To me, it feels as if it was good to merge.
Switching between chat permissions and setting permissions is not beautiful, but given the fact this is not a core interaction, I'd consider it "ok".

Bildschirmfoto 2019-08-08 um 19 40 45

It was great if we could get this merged, since it's a must for corporate, as per our compliance guys

@@ -0,0 +1,38 @@
import _ from 'underscore';
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The setting collection was used twice, so I refactored this into an own file.

@ggazzo
Copy link
Member

ggazzo commented Aug 13, 2019

image

@ggazzo
Copy link
Member

ggazzo commented Aug 15, 2019

@sampaiodiego could you review this code plz? I'm not worthy anymore (because I change the code a lot) =/ =) ...

ps: last thing I know, we have to move the streamer to emitter.js AND check if its everything ok because we gonna be sending the settings changes for all "manage-settings" users

ggazzo added 4 commits August 15, 2019 14:54
…' of github.com:assistify/Rocket.Chat into pr/8942-mrsimpson-core/RocketChat#8771-fine-granular-settings-permissions
@ggazzo ggazzo merged commit d19c721 into RocketChat:develop Aug 20, 2019
@rodrigok rodrigok changed the title [NEW] #8771 - fine granular settings permissions [NEW] Granular permissions for settings Aug 20, 2019
@geekgonecrazy geekgonecrazy deleted the core/#8771-fine-granular-settings-permissions branch August 20, 2019 15:13
mrsimpson added a commit to assistify/Rocket.Chat that referenced this pull request Aug 27, 2019
@sampaiodiego sampaiodiego mentioned this pull request Sep 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature request] More fine grained permission system
8 participants